package pub.developers.forum.infrastructure.file;


import com.alibaba.fastjson.JSON;
import com.aliyun.green20220302.Client;
import com.aliyun.green20220302.models.ImageModerationRequest;
import com.aliyun.green20220302.models.ImageModerationResponse;
import com.aliyun.green20220302.models.ImageModerationResponseBody;
import com.aliyun.green20220302.models.ImageModerationResponseBody.ImageModerationResponseBodyData;
import com.aliyun.green20220302.models.ImageModerationResponseBody.ImageModerationResponseBodyDataResult;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.teaopenapi.models.Config;
import com.aliyun.teautil.models.RuntimeOptions;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import net.coobird.thumbnailator.Thumbnails;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import pub.developers.forum.domain.service.OssFileService;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.text.SimpleDateFormat;
import java.util.*;

@Slf4j
@Data
@ConfigurationProperties(prefix = "custom-config.upload-file.oss")
@Component
public class OssFileServiceImpl implements OssFileService
{
    private String accessKey;

    private String secretKey;

    private String bucketName;

    private String endpoint;


    //设置获取client
    private Client  getClient() throws Exception {
//        DefaultProfile profile =  DefaultProfile.getProfile("cn-shenzhen", "LTAI5tJauxmFaobtVkgqg2Hb", "OkrjnoIAod8Oo8racrFM6RptKIjAHJ");
//        DefaultProfile.addEndpoint("cn-shenzhen", "Green", "green.cn-shenzhen.aliyuncs.com");
        Config config = new Config();
        config.setAccessKeyId(getAccessKey());
        config.setAccessKeySecret(getSecretKey());
        config.setEndpoint("green-cip.cn-shenzhen.aliyuncs.com");
        //实例化client , 重复使用可以提高检测性能
        return new Client(config);
    }

    //将图片上传到Oss
    @Override
    public String uploadImg(byte[] base64, String fileName , int type) {
        try {
            // 用于在OSS上命名，建议格式 ：年月日/文件名.后缀名，此时可以 以时间建立一个文件夹保存上传的图片
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
            String transformDate = simpleDateFormat.format(new Date());
            String objectName = transformDate + "/" + System.currentTimeMillis() + "_" + fileName;
            // 创建OSSClient实例。
            OSS ossClient = new OSSClientBuilder().build(endpoint, accessKey, secretKey);
            // 设置设置 HTTP 头 里边的 Content-Type
            ObjectMetadata objectMetadata = new ObjectMetadata();
            objectMetadata.setContentDisposition("inline");
            // 计算压缩参数
            double quality = calculateQuality(base64.length);
            //只要type类型传值了,就压缩
            // 如果检测到是官方上传的图片 , 则不能压缩 
            if (type != -1) {
                // 用户上传的图片，根据计算得到的压缩质量压缩
                base64 = compressPicForScale(base64, quality);
            }
            // 上传文件
            ossClient.putObject(bucketName, objectName, new ByteArrayInputStream(base64) , objectMetadata);
            String url = bucketName+"."+endpoint +"/"+ objectName;
            // 关闭OSSClient
            ossClient.shutdown();
            //如果是官方上传的图片,则不能审核
            if (type != -1)
            {
                //审核图片
                String err = checkUploadFile("https://"+url);
                if (err.equals("error")) {
                    //删除图片
                    OssFileServiceImpl ossFileService = new OssFileServiceImpl();
                    ossFileService.accessKey = accessKey;
                    ossFileService.endpoint = endpoint;
                    ossFileService.secretKey = secretKey;
                    ossFileService.bucketName = bucketName;
                    ////System.out.println("@@@"+objectName);
                    ossFileService.deleteImg(objectName);
                    return "error";
                }
            }
            return url;
        } catch (Exception e) {
            // 处理异常
            log.error("上传文件异常: " + e.getMessage(), e);
            // 返回错误状态或抛出自定义异常
            return "error";
        }
    }

    //审核上传的图片
    public String checkUploadFile(String url) throws Exception {
        Client client = getClient();

        // 创建RuntimeObject实例并设置运行参数
        RuntimeOptions runtime = new RuntimeOptions();

        // 检测参数构造。
        Map<String, String> serviceParameters = new HashMap<>();
        //公网可访问的URL。
        //System.out.println("url" +url);
        serviceParameters.put("imageUrl", url);
        //待检测数据唯一标识
        serviceParameters.put("dataId", UUID.randomUUID().toString());

        ImageModerationRequest request = new ImageModerationRequest();
        // 图片检测service：内容安全控制台图片增强版规则配置的serviceCode，示例：baselineCheck
        request.setService("aigcCheck");
        request.setServiceParameters(JSON.toJSONString(serviceParameters));

        ImageModerationResponse response = null;
        try {
            response = client.imageModerationWithOptions(request, runtime);
        } catch (Exception e) {
            e.printStackTrace();
        }
        //检测结果
        if (response != null)
        {
            if (response.getStatusCode() == 200)
            {
                ImageModerationResponseBody body = response.getBody();
                //System.out.println("requestId=" + body.getRequestId());
                //System.out.println("code=" + body.getCode());
                //System.out.println("msg=" + body.getMsg());
                if (body.getCode() == 200) {
                    ImageModerationResponseBodyData data = body.getData();
                    //System.out.println("dataId=" + data.getDataId());
                    List<ImageModerationResponseBodyDataResult> results = data.getResult();
                    for (ImageModerationResponseBodyDataResult result : results) {
                        //System.out.println("label=" + result.getLabel());
                        //System.out.println("confidence=" + result.getConfidence());
                        if ("nonLabel".equals(result.getLabel()))
                        {
                            return "pass";
                        }
                        return "error";
                    }
                } else {
                    log.error("image moderation not success. code:" + body.getCode());
                    return "error";
                }
            } else {
                log.error("response not success. status:" + response.getStatusCode());
                return "error";
            }
        }
        return "error";
    }


    @Override
    public String deleteImg(String key) {
        //////System.out.println(key);
        try {
            // 创建OSSClient实例。
            OSS ossClient = new OSSClientBuilder().build(endpoint, accessKey, secretKey);

            // 删除文件
            ossClient.deleteObject(bucketName , key);

            // 关闭OSSClient
            ossClient.shutdown();

            return "success";
        } catch (Exception e) {
            // 处理异常
            log.error("删除文件异常: " + e.getMessage(), e);
            // 返回错误状态或抛出自定义异常
            return "error";
        }
    }

    /**
     * 解决问题，直接访问上传的图片地址，会让下载而不是直接访问
     * 设置设置 HTTP 头 里边的 Content-Type
     * txt 格式经过测试，不需要转换 上传之后就是 text/plain。其他未测试
     * 已知  如果 Content-Type = .jpeg 访问地址会直接下载，本方法也是解决此问题
     * @param FilenameExtension
     * @return
     */
    public static String getcontentType(String FilenameExtension) {
        if (FilenameExtension.equalsIgnoreCase(".bmp")) {
            return "image/bmp";
        }
        if (FilenameExtension.equalsIgnoreCase(".gif")) {
            return "image/gif";
        }
        if (FilenameExtension.equalsIgnoreCase(".jpeg") ||
                FilenameExtension.equalsIgnoreCase(".jpg") ||
                FilenameExtension.equalsIgnoreCase(".png")) {
            return "image/jpg";
        }
        if (FilenameExtension.equalsIgnoreCase(".html")) {
            return "text/html";
        }

        if (FilenameExtension.equalsIgnoreCase(".txt")) {
            return "text/plain";
        }
        if (FilenameExtension.equalsIgnoreCase(".vsd")) {
            return "application/vnd.visio";
        }
        if (FilenameExtension.equalsIgnoreCase(".pptx") ||
                FilenameExtension.equalsIgnoreCase(".ppt")) {
            return "application/vnd.ms-powerpoint";
        }
        if (FilenameExtension.equalsIgnoreCase(".docx") ||
                FilenameExtension.equalsIgnoreCase(".doc")) {
            return "application/msword";
        }
        if (FilenameExtension.equalsIgnoreCase(".xml")) {
            return "text/xml";
        }
        return "image/jpg";
    }


    //尽最大努力保留图片精度
    private double calculateQuality(int imageSize) {
        // 根据图片大小动态调整压缩质量参数
        double quality = 0.85; // 默认压缩质量
        if (imageSize < 1024 * 500) {
            quality = 0.9; // 图片大小小于500KB时，提高压缩质量
        } else if (imageSize > 1024 * 2000) {
            quality = 0.8; // 图片大小大于2MB时，降低压缩质量
        }
        return quality;
    }
    //压缩图片
    private byte[] compressPicForScale(byte[] imageBytes, double quality) {
        try {
            // 压缩图片
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            Thumbnails.of(new ByteArrayInputStream(imageBytes))
                    .scale(1)
                    .outputQuality(quality)
                    .toOutputStream(outputStream);
            //图片压缩成功
            log.info("图片压缩成功");
            return outputStream.toByteArray();
        } catch (Exception e) {
            log.error("图片压缩失败: " + e.getMessage(), e);
            return imageBytes; // 如果压缩失败，返回原始图片数据
        }
    }

}
